package net.cyndeline.entitySystem

import net.cyndeline.EntityKey

trait EntityManager {
  
  def clear: Unit
  
  /**
   * @return A new unused entity reference.
   */
  def create: EntityRef
  
  /**
   * @@return A new unused entity reference with a set of components.
   */
  def create(component: Component*): EntityRef
  def create(component: Iterator[Component]): EntityRef
  
  def createEntityWithId(entityId: Int, components: Iterator[Component]): EntityRef
  def createEntityWithId(entityId: Int): EntityRef
  
  /**
   * @return The number of entities that contains a component of this type.
   */
  def componentCount(component: Class[_ <: Component]): Int
  
  /**
   * @return Iterator over all entities.
   */
  def iteratorEntities: Iterator[EntityRef]
//  
//  /**
//   * @return Iterator over all entities with the specified set of components.
//   */
//  def iteratorEntities(component: Class[Component]*): Iterator[EntityRef]
//  
//  /**
//   * @return Iterator of all mapped pairs of entities and the specified 
//   * 		 component class.
//   */
//  def iterateComponents[T <: Component](componentClass: Class[T]): Iterator[(EntityRef, Component)]
//  
  /**
   * Retrieve a unique entity based on a key.
   */
  def keyEntity(key: EntityKey): Option[EntityRef]
  
  /**
   * Map a unique entity to a key, making it easier to retrieve it.
   */
  def addKeyEntity(key: EntityKey, entity: EntityRef)
  
  /**
   * @return The event system used by this manager.
   */
  def eventSystem: Option[EventSystem]
  
  /**
   * Sets a new event system.
   */
  def setEventSystem(eventSystem: EventSystem ): Unit
  
  /**
   * @return The number of active entities.
   */
  def activeEntities: Int
  
  /**
   * @return True if an entity contains a component of the specified type.
   */
  def hasComponent(entityId: Int, componentClass: Class[_ <: Component]): Boolean
  
  /**
   * @return An iterator over every component an entity has.
   */
  def iterateComponents(entityId: Int): Iterator[Component]
  
  /**
   * Nulls an entity and removes all data it contains from the manager, as well
   * as freeing up the entitys id.
   */
  def destroy(entityId: Int): Unit
  
  /**
   * @return A component of the specified type that the entity contains.
   */
  def getComponent[A <: Component](entityId: Int, componentClass: Class[A]): Option[_ <: Component]
  
  /**
   * Adds a component to an entity.
   * @return The component that was added.
   */
  def addComponent[T <: Component](entityId: Int, component: T): T
  
  /**
   * Removes a component from an entity.
   */
  def removeComponent(entityId: Int, componentClass: Class[_ <: Component]): Unit
  
  /**
   * Copies the set of components of an entityref and returns a new entity
   * with the new component set.
   */
  def copy(other: EntityRef): EntityRef
}